
#include <windows.h>
#include "CDXSwapChain.h"
#include "CDXRenderer.h"
#include "CReleaseMacro.h"


CDXRenderer* g_pRender = NULL;
CDXDevice* g_pDevice = NULL;
CDXSwapChain* g_pSwapChain = NULL;
CDXTexture2D* g_pTexture = NULL;
CDXTexture2D* g_pTextureRT = NULL;
CDXTexture2D* g_pTextureBorder = NULL;

IDWriteTextFormat* g_TextFmt = NULL;
IDWriteTextLayout* g_TextLayout = NULL;


VOID Render();
//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
	CoInitialize(0);
	HRESULT hr = S_OK;
	g_pDevice = new CDXDevice();
	
	WCHAR str[MAX_PATH] = L"MUI Test Text!!!";
	g_pDevice->CreateTextLayout(&g_TextLayout, str, wcslen(str), 400, 400,  72);


	g_pSwapChain = new CDXSwapChain(g_pDevice);
	g_pSwapChain->Create(hWnd);

	g_pTexture = new CDXTexture2D(g_pDevice);
	hr = g_pTexture->LoadFromFile(L"D:\\Personal Data\\picture\\Penny.jpg");
	
	g_pTextureBorder = new CDXTexture2D(g_pDevice);
	hr = g_pTextureBorder->LoadFromFile(L"D:\\Projects\\PyCharm_Project\\PyMUI\\resourceData\\UIImages\\button\\btn_n.png");

	D3D11_TEXTURE2D_DESC desc;
	desc.Width =1024;
	desc.Height = 768;
	desc.MipLevels = 1;
	desc.ArraySize = 1;
	desc.Usage = D3D11_USAGE_DEFAULT;
	desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	desc.SampleDesc.Count = 1;
	desc.SampleDesc.Quality = 0; 
	desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
	desc.CPUAccessFlags = 0;
	desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
	
	g_pTextureRT = new CDXTexture2D(g_pDevice);
	g_pTextureRT->Create(&desc);

	g_pRender = new CDXRenderer(g_pDevice);
	hr = g_pRender->SetFrameBuffer(g_pSwapChain);

	Render();
	
    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    SAFE_RELEASE(g_pDevice);
	SAFE_RELEASE(g_pRender);
	SAFE_RELEASE(g_pTexture);
	SAFE_RELEASE(g_pTextureRT);
	SAFE_RELEASE(g_pTextureBorder);
	SAFE_RELEASE(g_pSwapChain);
	SAFE_RELEASE(g_TextFmt);
	CoUninitialize();
}




//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
	static DWORD timecount = 0;
	static DWORD timeStart = timeGetTime();
	timecount++;
	DWORD t = timeGetTime();
	t = (t % 20000) ;
	static float c = 0;
	c += 0.001;
	if (c > 1)
	{
		c = 0;
	}
	float clearColor[4] = {c,1,0,1};
	

	/*ID2D1RenderTarget* pD2DRT = NULL;
	g_pTexture->GetD2DRenderTarget(&pD2DRT);
	D2D_COLOR_F d2dColor = {1, 0, 0, 1};
	g_pRender->BeginDraw();
	pD2DRT->Clear(d2dColor);
	g_pRender->EndDraw();*/
	
	D2D1_RECT_F rect = D2D1::RectF(10, 10, 80, 80);
	D2D1_RECT_F rect2= {10, 90, 410, 490};
	float color[4] = {1.0, 0, 0, 0.8};
	float clrRed[4] = {1.0, 0, 0, 1.0};
	g_pRender->BeginDraw();
	
	g_pRender->ClearColor(clearColor);
	//g_pRender->PushAxisAlignedClip(D2D1::RectF(10, 10, 100, 100), D2D1_ANTIALIAS_MODE_ALIASED );

	g_pRender->PushMatrix();
	g_pRender->Translate(-45, -45, 0);
	g_pRender->RotateAxis( &D3DXVECTOR3(0,0,1), t*0.01);
	g_pRender->Translate(45, 45, 0);
	g_pRender->DrawBitmap(g_pTexture, rect);
	g_pRender->PopMatrix();

	float bw[4] = {8,8,8,8};
	g_pRender->DrawBitmap(g_pTexture, rect2, Fill);
	//g_pRender->DrawBitmap(g_pTextureBorder, rect2);
	g_pRender->DrawTextLayout(D2D1::Point2F(300, 300), g_TextLayout, color);
	
	//g_pRender->PopAxisAlignedClip();
	g_pRender->BeginDrawD3D();
	
	
	g_pRender->PushMatrix();
	//g_pRender->RotateAxis( &D3DXVECTOR3(0,1,0), t*0.01);
	
	float white[4] = {1, 1, 1, 1};
	g_pRender->DrawRectangleD3D(D2D1::RectF(10, 500, 210, 550), g_pTexture, white, UniformFill);
	
	//g_pRender->DrawRectangleD3D(D2D1::RectF(10, 500, 300, 700), g_pTextureBorder, white);
	g_pRender->PopMatrix();
	g_pRender->EndDrawD3D();
	
	g_pRender->DrawRectangle(D2D1::RectF(10, 500, 210, 550), clrRed, 3.0);
	g_pRender->DrawRectangle(rect2, clrRed, 3.0);
	float eclClr[4] = {0.3, 0.7, 0.3, 1.0};
	g_pRender->FillEllipse(D2D1::Ellipse(D2D1::Point2F(100, 150), 30, 40), eclClr);
	float eclClr2[6] = {0.3, 0.7, 1.0, 1.0};
	g_pRender->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(100, 150), 30, 40), eclClr2, 5);

	g_pRender->EndDraw();


	

	g_pSwapChain->Present();
	
	if (timecount % 1000  == 0)
	{
		DWORD timeEnd = timeGetTime();
		DWORD timeDiff = timeEnd - timeStart;
		if (timeDiff > 0)
		{
			timeStart = timeEnd;
			float fps = (float)timecount / timeDiff * 1000;
			static WCHAR str[MAX_PATH];
			swprintf(str, L"FPS: %.3f\n", fps);
			OutputDebugString(str);
			timecount = 0;
		}
	}

	
}




//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            break;

        case WM_PAINT:
            Render();
            ValidateRect( hWnd, NULL );
            break;
		case WM_SIZE:
			{
				UINT width = LOWORD(lParam);
				UINT height = HIWORD(lParam);
				if (g_pSwapChain != NULL)
				{
					g_pSwapChain->ResizeBuffer(width, height);
				}
				if (g_pRender != NULL)
				{
					g_pRender->UpdateViewportByFrameBuf();
					g_pRender->UpdateCamViewByViewport();
				}
			}
			break;
			
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}




//-----------------------------------------------------------------------------
// Name: wWinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
    UNREFERENCED_PARAMETER( hInst );

    // Register the window class
    WNDCLASSEX wc =
    {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
        L"D3D Tutorial", NULL
    };
    RegisterClassEx( &wc );

    // Create the application's window
    HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 01: CDXTest",
                              WS_OVERLAPPEDWINDOW, 100, 100, 1024, 768,
                              NULL, NULL, wc.hInstance, NULL );

    // Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        // Show the window
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );

        // Enter the message loop
		MSG msg;
		ZeroMemory( &msg, sizeof( msg ) );
		while( msg.message != WM_QUIT )
		{
			if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
			else
				Render();
		}
    }

    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}



